﻿using CMS.Controls.Messages;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace CMS.Controls.TabPageTemplate
{
    public class EditorTabPage : Panel
    {
        #region 界面组件
        private GroupBox GB_Preview;
        private ListBox LB_Preview;
        private ContextMenuStrip CMS_Preview;
        private ToolStripMenuItem TSMI_NewItem;
        private ToolStripMenuItem TSMI_DeleteItems;
        private ToolStripMenuItem TSMI_RefreshItems;
        private GroupBox GB_Editor;
        private Panel P_Editor;
        private Button Bn_EditLock;
        private Button Bn_Save;

        #endregion

        #region 私有字段
        /// <summary>
        /// 列表项的宽度占父类的百分比
        /// </summary>
        private int _ListWidthPercent = 20;

        /// <summary>
        /// 适配器
        /// </summary>
        private EditorAdaptor _Adapter;

        /// <summary>
        /// 编辑锁
        /// </summary>
        private bool _Locked = true;

        /// <summary>
        /// 是否已经初始化界面
        /// </summary>
        private bool _InitializedControl = true;

        #endregion

        #region 公共属性
        [Description("列表项的宽度占父类的百分比")]
        public int ListWidthPercent
        {
            get => _ListWidthPercent; set
            {
                if (value <= 0 || value > 100)
                {
                    throw new IndexOutOfRangeException();
                }

                _ListWidthPercent = value;
            }
        }

        [Description("列表项和编辑框之间的距离")]
        public int InnerPadding { get; set; } = 20;

        /// <summary>
        /// 适配器决定了显示方式
        /// </summary>
        public EditorAdaptor Adaptor
        {
            get => _Adapter; set
            {
                if (_Adapter != null)
                {
                    _Adapter.MessageSending -= _Adapter_MessageSending;
                }

                _Adapter = value ?? throw new ArgumentNullException();
                _Adapter.MessageSending += _Adapter_MessageSending;
                if (_Adapter.AllowIndexItem)
                {
                    _InitializedControl = true;
                    OnResetAdapterBinding();
                }
                else
                {
                    _InitializedControl = false;
                    _ShowForbiddenMessage();
                }
            }
        }


        private void _Adapter_MessageSending(object sender, Messages.MessageSentEventArgs e)
        {
            if (FindForm() is IMessageDestination dest)
            {
                dest.ReceiveMessage(e);
            }
        }



        #endregion


        public EditorTabPage()
        {
            //InitializeComponent();

        }

        private void _InitializeComponent()
        {
            SuspendLayout();
            Controls.Clear();
            //This
            Padding = new Padding(20);
            BackColor = Color.White;

            //Create New Control
            GB_Preview = new GroupBox();
            LB_Preview = new ListBox();
            CMS_Preview = new ContextMenuStrip();
            TSMI_NewItem = new ToolStripMenuItem();
            TSMI_DeleteItems = new ToolStripMenuItem();
            TSMI_RefreshItems = new ToolStripMenuItem();
            GB_Editor = new GroupBox();
            P_Editor = new Panel();
            Bn_EditLock = new Button();
            Bn_Save = new Button();

            //GB_Preview
            GB_Preview.Padding = new Padding(5);
            GB_Preview.Text = "所有" + _Adapter.ItemName;

            //LB_Preview
            LB_Preview.Dock = DockStyle.Fill;
            LB_Preview.Font = new Font("微软雅黑", 16, FontStyle.Regular, GraphicsUnit.Pixel);
            LB_Preview.SelectionMode = SelectionMode.MultiExtended;
            LB_Preview.DataSource = _Adapter.MainListSource;
            LB_Preview.ContextMenuStrip = CMS_Preview;
            LB_Preview.IntegralHeight = false;
            LB_Preview.ScrollAlwaysVisible = true;
            LB_Preview.SelectedIndexChanged += LB_Preview_SelectedIndexChanged;
            LB_Preview.DisplayMember = Adaptor.NameField;

            //GB_Editor
            GB_Editor.Text = "编辑" + _Adapter.ItemName;
            GB_Editor.Padding = new Padding(10);

            //CMS_Preview
            CMS_Preview.Opening += CMS_Preview_Opening;
            TSMI_NewItem.Text = "新增" + _Adapter.ItemName;
            TSMI_NewItem.Image = Resource1.New16;
            TSMI_NewItem.Click += TSMI_NewItem_Click;

            TSMI_DeleteItems.Text = "删除" + _Adapter.ItemName;
            TSMI_DeleteItems.Image = Resource1.Delete16;
            TSMI_DeleteItems.Click += TSMI_DeleteItems_Click;

            TSMI_RefreshItems.Text = "刷新列表";
            TSMI_RefreshItems.Image = Resource1.Refresh16;
            TSMI_RefreshItems.Click += TSMI_RefreshItems_Click;

            CMS_Preview.Items.Add(TSMI_NewItem);
            CMS_Preview.Items.Add(TSMI_DeleteItems);
            CMS_Preview.Items.Add(new ToolStripSeparator());
            CMS_Preview.Items.Add(TSMI_RefreshItems);

            //P_Editor
            //P_Editor.BorderStyle = BorderStyle.FixedSingle;
            P_Editor.Location = new Point(GB_Editor.Padding.Left, GB_Editor.Padding.Top + 10);
            P_Editor.Size = new Size(GB_Editor.Width - GB_Editor.Padding.Left - GB_Editor.Padding.Right, GB_Editor.Height - GB_Editor.Padding.Top - GB_Editor.Padding.Bottom * 2 - 30);
            P_Editor.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
            Adaptor.InitializeEditor(P_Editor, Adaptor.EditorSource);

            //Bn_Save
            Bn_Save.Size = new Size(60, 25);
            Bn_Save.Image = Resource1.Save16;
            Bn_Save.ImageAlign = ContentAlignment.MiddleLeft;
            Bn_Save.TextAlign = ContentAlignment.MiddleRight;
            Bn_Save.Text = "保存";
            Bn_Save.BackColor = SystemColors.Control;
            Bn_Save.Location = new Point(GB_Editor.Width - Bn_Save.Width - GB_Editor.Padding.Right, GB_Editor.Height - Bn_Save.Height - GB_Editor.Padding.Bottom);
            Bn_Save.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
            Bn_Save.Click += Bn_Save_Click;

            //Bn_EditLock
            _Locked = true;
            Bn_EditLock.Size = new Size(60, 25);
            Bn_EditLock.Image = Resource1.Lock16;
            Bn_EditLock.ImageAlign = ContentAlignment.MiddleLeft;
            Bn_EditLock.TextAlign = ContentAlignment.MiddleRight;
            Bn_EditLock.Text = "编辑";
            Bn_EditLock.BackColor = SystemColors.Control;
            Bn_EditLock.Enabled = Adaptor.AllowUpdateItem;
            Bn_EditLock.Location = new Point(Bn_Save.Left - Bn_EditLock.Width - 15, Bn_Save.Top);
            Bn_EditLock.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
            Bn_EditLock.Click += Bn_EditLock_Click;

            GB_Preview.Controls.Add(LB_Preview);
            GB_Editor.Controls.Add(P_Editor);
            GB_Editor.Controls.Add(Bn_EditLock);
            GB_Editor.Controls.Add(Bn_Save);

            Controls.Add(GB_Preview);
            Controls.Add(GB_Editor);
            ResumeLayout();
        }

        private void _ShowForbiddenMessage()
        {
            //SuspendLayout();
            Controls.Clear();

            Label label = new Label()
            {
                Text = "      很抱歉,您的账号权限不足以访问此选项卡",
                Font = new Font("微软雅黑", 20),
                ForeColor = Color.Gray,
                Size = new Size(700, 300),
                Location = Point.Empty,
                Padding = new Padding(50),
                Image = Resource1.Permission64,
                ImageAlign = ContentAlignment.MiddleLeft,
                TextAlign = ContentAlignment.MiddleRight
            };
            Controls.Add(label);
        }

        private void Bn_Save_Click(object sender, EventArgs e)
        {
            Adaptor.OnSaveItem();
        }

        private void LB_Preview_SelectedIndexChanged(object sender, EventArgs e)
        {
            int count = LB_Preview.SelectedItems.Count;
            if (count == 1)
            {
                GB_Editor.Enabled = true;
                if (!Adaptor.AllowUpdateItem)
                {
                    _Locked = true;
                    UpdateEditButton();
                }
                if (_Locked)
                {
                    Adaptor.OnDisplayItem(P_Editor, LB_Preview.SelectedItem);
                }
                else
                {
                    Adaptor.OnEditItem(P_Editor, LB_Preview.SelectedItem);
                }
            }
            else
            {
                GB_Editor.Enabled = false;
                Adaptor.OnDisableEditor(P_Editor);
            }
        }

        private void UpdateEditButton()
        {
            if (_Locked)
            {
                Bn_EditLock.Image = Resource1.Lock16;
                Bn_Save.Enabled = false;
            }
            else
            {
                Bn_EditLock.Image = Resource1.Unlock16;
                Bn_Save.Enabled = true;
            }
        }

        private void Bn_EditLock_Click(object sender, EventArgs e)
        {
            _Locked = !_Locked;
            UpdateEditButton();
            if (LB_Preview.SelectedItems.Count == 1)
            {
                if (_Locked)
                {
                    Adaptor.OnDisplayItem(P_Editor, LB_Preview.SelectedItem);
                }
                else
                {
                    Adaptor.OnEditItem(P_Editor, LB_Preview.SelectedItem);
                }
            }
            else
            {
                Adaptor.OnDisableEditor(P_Editor);
            }
        }

        private void TSMI_RefreshItems_Click(object sender, EventArgs e)
        {
            _Adapter.OnRefrshList();
        }

        private void TSMI_DeleteItems_Click(object sender, EventArgs e)
        {
            _Adapter.OnDeleteItems(LB_Preview.SelectedItems.OfType<object>().ToArray());
        }

        private void TSMI_NewItem_Click(object sender, EventArgs e)
        {
            GB_Editor.Enabled = true;
            _Locked = false;
            UpdateEditButton();
            _Adapter.OnCreateItem(P_Editor);
        }

        private void CMS_Preview_Opening(object sender, CancelEventArgs e)
        {
            TSMI_NewItem.Enabled = _Adapter.AllowCreateItem;
            int count = LB_Preview.SelectedItems.Count;
            if (count != 0)
            {
                Point pos = LB_Preview.PointToClient(Cursor.Position);
                if (!LB_Preview.SelectedIndices.OfType<int>().Any(index => LB_Preview.GetItemRectangle(index).Contains(pos)))
                {
                    LB_Preview.ClearSelected();
                    LB_Preview.ClearSelected();
                    count = 0;
                }
            }

            if (count == 0)
            {
                TSMI_DeleteItems.Text = "删除" + _Adapter.ItemName;
                TSMI_DeleteItems.Enabled = false;
            }
            else
            {
                if (count == 1)
                {
                    TSMI_DeleteItems.Text = "删除" + LB_Preview.GetItemText(LB_Preview.SelectedItem);
                }
                else
                {
                    TSMI_DeleteItems.Text = "删除多个" + _Adapter.ItemName;
                }

                TSMI_DeleteItems.Enabled = _Adapter.AllowDeleteItem;
            }
        }

        /// <summary>
        /// 重置适配器的绑定
        /// </summary>
        private void OnResetAdapterBinding()
        {
            _Adapter.OnRefrshList();
            _InitializeComponent();
            LB_Preview.SelectedIndex = -1;
            _Adapter.UpdateDisplayMode(P_Editor, EditorAdaptor.DisplayMode.None);
        }

        protected override void OnLayout(LayoutEventArgs levent)
        {
            base.OnLayout(levent);
            if (_InitializedControl)
            {
                int restWidth = Width - Padding.Left - Padding.Right;
                int restHeight = Height - Padding.Top - Padding.Bottom;
                int listWidth = (restWidth - InnerPadding) * _ListWidthPercent / 100;
                GB_Preview.Location = new Point(Padding.Left, Padding.Top);
                GB_Preview.Size = new Size(listWidth, restHeight);

                GB_Editor.Location = new Point(listWidth + Padding.Left + InnerPadding, Padding.Top);
                GB_Editor.Size = new Size(restWidth - InnerPadding - listWidth, restHeight);
            }
        }

    }
}
